package csen;

import java.util.*;

public class CarStore implements Subject {

	private ArrayList<Observer> observers = new ArrayList<Observer>();
	private ArrayList<Car> availableCars = new ArrayList<Car>();
	private HashMap<String, Car> orders = new HashMap<String, Car>();

	public void addCar(Car car) {
		availableCars.add(car);
		notifyObservers("add", car);
	}

	public boolean removeCar(Car car) {
		notifyObservers("remove", car);
		return availableCars.remove(car);
	}

	/**
	 * if the car is available the order is placed
	 * 
	 * @param car
	 * @return id or null if the opperation fails
	 */
	public String createOrder(Car car) {
		if (availableCars.contains(car)) {
			UUID id = UUID.randomUUID();
			orders.put(id.toString(), car);
			availableCars.remove(car);
			notifyObservers("createOrder", car);
			return id.toString();
		} else {
			return null;
		}
	}

	/**
	 * the car is made available again
	 * 
	 * @param id
	 * @return true or false if the opperation fails
	 */
	public boolean cancelOrder(String id) {
		Car car = orders.get(id);
		if (car != null) {
			orders.remove(id);
			notifyObservers("cancelOrder", car);
			addCar(car);
			return true;
		} else {
			return false;
		}
	}

	/**
	 * the car is sold
	 * 
	 * @param id
	 * @return true or false if the opperation fails
	 */
	public boolean approveOrder(String id) {
		Car car = orders.get(id);
		if (car != null) {
			orders.remove(id);
			notifyObservers("approveOrder", car);
			return true;
		} else {
			return false;
		}
	}

	/**
	 * checks if the car is ordered by someone
	 * 
	 * @param id
	 * @return true or false
	 */
	public boolean isOrdered(String id) {
		return orders.containsKey(id);
	}

	/**
	 * 
	 * @param brand
	 * @return list of cars that match the criteria
	 */
	public ArrayList<Car> search(String brand) {
		ArrayList<Car> foundCars = new ArrayList<Car>();
		for (Car car : availableCars) {
			if (car.getBrand().equals(brand)) {
				foundCars.add(car);
			}
		}
		return foundCars;
	}

	/**
	 * 
	 * @param lowPrice
	 * @param highPrice
	 * @return list of cars that match the criteria
	 */
	public ArrayList<Car> search(int lowPrice, int highPrice) {
		ArrayList<Car> foundCars = new ArrayList<Car>();
		for (Car car : availableCars) {
			int price = car.getPrice();
			if ((price > lowPrice) && (price < highPrice)) {
				foundCars.add(car);
			}
		}
		return foundCars;
	}

	@Override
	public void registerObserver(Observer observer) {
		observers.add(observer);
	}

	@Override
	public void removeObserver(Observer observer) {
		observers.remove(observer);
	}

	@Override
	public void notifyObservers(String opperationType, Car car) {
		for (Observer ob : observers) {
			ob.update(opperationType, car);
		}
	}

}
